package rpc.aop;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.Map;

public class XiaobaibaiClientProxyRegister implements BeanDefinitionRegistryPostProcessor {

    /**
     * BeanDefinitionRegistryPostProcessor接口用于生成bean定义信息或者修改bean定义信息。
     */

    private String basePackage;

    private BeanDefinitionRegistry registry;

    /**
     * 可以修改增加BeanDefinition。此特性可以用来动态生成bean，比如读取某个配置项，然后根据配置项动态生成bean。
     */
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        //用于注册更多的bean到spring容器中
        this.registry=registry;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        //进入此方法时,所有的bean信息都转为了beanDefinition,此时加载和注册完毕,但还没有进行初始化;修改bean定义信息的最佳时机。
        /**
         * 这么做是为了获取启动类所扫描的包,更保险的可以获取@ComponentScan注解类(因为开发者可能设置多个扫描注解)
         */
        Map<String, Object> beansWithAnnotation = configurableListableBeanFactory.getBeansWithAnnotation(SpringBootApplication.class);
        Class clazz = beansWithAnnotation.values().toArray()[0].getClass();
        this.basePackage=clazz.getPackage().getName();
        if (StringUtils.isEmpty(basePackage)) {
            return;
        }
        //为scanner类服务,传入注册实例;
        XiaobaibaiClientInterfacesScanner scanner = new XiaobaibaiClientInterfacesScanner(registry);
        scanner.doScan(basePackage);
    }

}